package org.lanyu.springainovel.common.service;

import lombok.extern.slf4j.Slf4j;
import org.lanyu.springainovel.common.dto.UnifiedTaskMessage;
import org.lanyu.springainovel.common.entity.TaskNotification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * 通用异步任务WebSocket服务
 */
@Slf4j
@Service
public class AsyncTaskWebSocketService {
    
    @Autowired
    private SimpMessagingTemplate messagingTemplate;
    
    @Autowired
    private TaskNotificationService taskNotificationService;
    
    /**
     * 发送统一格式的任务消息
     * 
     * @param type 功能模块类型，如"outline", "chapter", "analysis"等
     * @param taskId 任务唯一标识，如"bookid_outline", "bookid_chapter_num"等
     * @param status 任务状态
     * @param progress 任务进度
     * @param message 消息内容
     */
    public void sendUnifiedTaskMessage(String type, String taskId, String status, Integer progress, String message) {
        UnifiedTaskMessage unifiedMessage = new UnifiedTaskMessage(type, taskId, status, progress, message);
        
        // 发送到统一的消息主题
        messagingTemplate.convertAndSend("/topic/unified-task", unifiedMessage);
    }
    
    /**
     * 发送任务开始消息
     */
    public void sendTaskStart(String type, String taskId, String message) {
        sendUnifiedTaskMessage(type, taskId, "STARTED", 0, message);
    }
    
    /**
     * 发送任务进度更新消息
     */
    public void sendTaskProgress(String type, String taskId, Integer progress, String message) {
        sendUnifiedTaskMessage(type, taskId, "PROCESSING", progress, message);
    }
    
    /**
     * 发送任务完成消息
     */
    public void sendTaskComplete(String type, String taskId, String message) {
        sendUnifiedTaskMessage(type, taskId, "COMPLETED", 100, message);
    }
    
    /**
     * 发送任务失败消息
     */
    public void sendTaskFailed(String type, String taskId, String message) {
        sendUnifiedTaskMessage(type, taskId, "FAILED", null, message);
    }
    
    /**
     * 发送任务进度更新
     * 
     * @param taskId 任务ID
     * @param progress 进度百分比 (0-100)
     * @param message 进度消息
     */
    public void sendTaskProgress(String taskId, int progress, String message) {
        Map<String, Object> payload = new HashMap<>();
        payload.put("taskId", taskId);
        payload.put("progress", progress);
        payload.put("message", message);
        payload.put("timestamp", System.currentTimeMillis());
        
        // 向特定任务ID的主题发送消息
        messagingTemplate.convertAndSend("/topic/task/" + taskId + "/progress", payload);
        
        // 同时发送到统一消息主题，使用"进度更新"作为类型
        sendUnifiedTaskMessage("进度更新", taskId, "RUNNING", progress, message);
    }
    
    /**
     * 发送任务状态更新
     * 
     * @param taskId 任务ID
     * @param status 任务状态
     * @param message 状态消息
     */
    public void sendTaskStatusUpdate(String taskId, String status, String message) {
        Map<String, Object> payload = new HashMap<>();
        payload.put("taskId", taskId);
        payload.put("status", status);
        payload.put("message", message);
        payload.put("timestamp", System.currentTimeMillis());
        
        // 向特定任务ID的主题发送消息
        messagingTemplate.convertAndSend("/topic/task/" + taskId + "/status", payload);
        
        // 同时发送到统一消息主题，使用"状态更新"作为类型
        sendUnifiedTaskMessage("状态更新", taskId, status, null, message);
    }
    
    /**
     * 发送任务完成通知
     * 
     * @param taskId 任务ID
     * @param result 任务结果
     */
    public void sendTaskCompletion(String taskId, Object result) {
        Map<String, Object> payload = new HashMap<>();
        payload.put("taskId", taskId);
        payload.put("status", "COMPLETED");
        payload.put("result", result);
        payload.put("timestamp", System.currentTimeMillis());
        
        // 向特定任务ID的主题发送消息
        messagingTemplate.convertAndSend("/topic/task/" + taskId + "/completion", payload);
        
        // 同时发送到统一消息主题，使用"任务完成"作为类型
        sendUnifiedTaskMessage("任务完成", taskId, "COMPLETED", 100, "任务已完成");
    }
    
    /**
     * 发送任务失败通知
     * 
     * @param taskId 任务ID
     * @param errorMessage 错误信息
     */
    public void sendTaskFailure(String taskId, String errorMessage) {
        Map<String, Object> payload = new HashMap<>();
        payload.put("taskId", taskId);
        payload.put("status", "FAILED");
        payload.put("message", errorMessage);
        payload.put("timestamp", System.currentTimeMillis());
        
        // 向特定任务ID的主题发送消息
        messagingTemplate.convertAndSend("/topic/task/" + taskId + "/failure", payload);
        
        // 同时发送到统一消息主题，使用"任务失败"作为类型
        sendUnifiedTaskMessage("任务失败", taskId, "FAILED", null, errorMessage);
    }
    
    /**
     * 发送大纲生成特定消息
     * 
     * @param bookId 书籍ID
     * @param status 任务状态
     * @param progress 任务进度
     * @param msg 消息内容
     * @param result 任务结果（可选）
     */
    public void sendOutlineGenerationMessage(String bookId, String status, Integer progress, String msg, Object result) {
        sendUnifiedTaskMessage("大纲生成", bookId, status, progress, msg);
    }
    
    /**
     * 发送章节生成特定消息
     * 
     * @param bookId 书籍ID
     * @param status 任务状态
     * @param progress 任务进度
     * @param msg 消息内容
     * @param result 任务结果（可选）
     */
    public void sendChapterGenerationMessage(String bookId, String status, Integer progress, String msg, Object result) {
        sendUnifiedTaskMessage("章节生成", bookId, status, progress, msg);
    }
    
    /**
     * 发送章节细纲生成特定消息
     * 
     * @param bookId 书籍ID
     * @param status 任务状态
     * @param progress 任务进度
     * @param msg 消息内容
     * @param result 任务结果（可选）
     */
    public void sendChapterOutlineGenerationMessage(String bookId, String status, Integer progress, String msg, Object result) {
        sendUnifiedTaskMessage("章节细纲生成", bookId, status, progress, msg);
    }
    
    /**
     * 发送章节内容生成特定消息
     * 
     * @param bookId 书籍ID
     * @param chapterNumber 章节号
     * @param status 任务状态
     * @param progress 任务进度
     * @param msg 消息内容
     * @param result 任务结果（可选）
     */
    public void sendChapterContentGenerationMessage(String bookId, String chapterNumber, String status, Integer progress, String msg, Object result) {
        String taskId = bookId + "_" + chapterNumber;
        sendUnifiedTaskMessage("章节内容生成", taskId, status, progress, msg);
    }
    
    /**
     * 发送通知到用户
     * 
     * @param userId 用户ID
     * @param taskNotification 任务通知对象
     */
    public void sendNotificationToUser(Long userId, TaskNotification taskNotification) {
        try {
            // 发送到用户的通知主题
            messagingTemplate.convertAndSend("/topic/user/" + userId + "/notifications", taskNotification);
            
            log.debug("发送通知到用户: userId={}, notificationId={}", userId, taskNotification.getId());
        } catch (Exception e) {
            log.error("发送通知到用户失败: userId={}, notificationId={}", userId, taskNotification.getId(), e);
        }
    }
    
    /**
     * 发送任务完成通知并保存到数据库
     * 
     * @param userId 用户ID
     * @param taskId 任务ID
     * @param taskType 任务类型
     * @param taskName 任务名称
     * @param success 是否成功
     * @param errorMessage 错误信息（失败时）
     */
    public void sendTaskCompletionNotification(Long userId, String taskId, String taskType, 
                                             String taskName, boolean success, String errorMessage) {
        try {
            TaskNotification taskNotification;
            
            if (success) {
                // 创建成功通知
                taskNotification = taskNotificationService.createNotification(
                    userId, 
                    taskName + "完成", 
                    taskName + "已成功完成", 
                    "INFO"
                );
            } else {
                // 创建失败通知
                taskNotification = taskNotificationService.createNotification(
                    userId, 
                    taskName + "失败", 
                    taskName + "执行失败: " + errorMessage, 
                    "ERROR"
                );
            }
            
            // 发送WebSocket通知
            sendNotificationToUser(userId, taskNotification);
            
            log.info("发送任务完成通知: userId={}, taskId={}, taskType={}, success={}", 
                    userId, taskId, taskType, success);
        } catch (Exception e) {
            log.error("发送任务完成通知失败: userId={}, taskId={}", userId, taskId, e);
        }
    }
}